package v1

import (
	"errors"
	"fmt"
	"strconv"

	// "wms/internal/model" // 移除未使用的导入
	"wms/internal/model/request"
	"wms/internal/model/response"
	"wms/internal/service"
	"wms/pkg/common"
	"wms/pkg/logger"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// UserController 用户控制器
type UserController struct {
	userService *service.UserService
}

// NewUserController 创建用户控制器
func NewUserController() *UserController {
	return &UserController{
		userService: service.NewUserService(),
	}
}

// Login godoc
// @Summary 用户登录
// @Description 用户登录并返回token
// @Tags 认证管理
// @Accept json
// @Produce json
// @Param request body request.LoginRequest true "登录信息"
// @Success 200 {object} resp.Response{data=response.LoginResponse} "登录成功"
// @Failure 400 {object} resp.Response "请求错误"
// @Router /auth/login [post]
func (c *UserController) Login(ctx *gin.Context) {
	var req request.LoginRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定登录请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// 获取用户IP地址
	req.IP = ctx.ClientIP()

	data, err := c.userService.Login(&req)
	if err != nil {
		logger.Error("用户登录失败", zap.Error(err), zap.Any("req", req))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, data)
}

// Logout godoc
// @Summary 用户登出
// @Description 用户退出登录
// @Tags 认证管理
// @Accept json
// @Produce json
// @Success 200 {object} resp.Response "登出成功"
// @Router /auth/logout [post]
func (c *UserController) Logout(ctx *gin.Context) {
	// 登出逻辑简单，只需返回成功即可，JWT token由前端清除
	common.Success(ctx, nil)
}

// GetList godoc
// @Summary 获取用户列表
// @Description 获取用户列表，支持分页和搜索
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param keyword query string false "搜索关键词"
// @Success 200 {object} resp.Response{data=response.PageData{list=[]model.User}} "成功"
// @Router /users [get]
func (c *UserController) GetList(ctx *gin.Context) {
	var req request.UserListRequest
	if err := ctx.ShouldBindQuery(&req); err != nil {
		logger.Warn("绑定用户列表请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	users, total, err := c.userService.GetUsers(&req)
	if err != nil {
		logger.Error("获取用户列表失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, gin.H{
		"list":  users,
		"total": total,
		"page":  req.Page,
		"size":  req.PageSize,
	})
}

// Create godoc
// @Summary 创建用户
// @Description 创建新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body request.UserCreateRequest true "用户信息"
// @Success 200 {object} resp.Response "成功"
// @Router /users [post]
func (c *UserController) Create(ctx *gin.Context) {
	var req request.UserCreateRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定创建用户请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	if err := c.userService.CreateUser(&req); err != nil {
		logger.Error("创建用户失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// GetInfo godoc
// @Summary 获取用户信息
// @Description 获取指定用户的详细信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "用户ID"
// @Success 200 {object} resp.Response{data=model.User} "成功"
// @Router /users/{id} [get]
func (c *UserController) GetInfo(ctx *gin.Context) {
	idParam := ctx.Param("id")
	logger.Info("获取用户详情，ID参数", zap.String("id", idParam))

	// 检查ID是否为"info"，这应该由其他路由处理
	if idParam == "info" {
		logger.Error("请求/users/info被错误地路由到GetInfo方法")
		common.Error(ctx, errors.New("API路由配置错误"))
		return
	}

	id, err := strconv.ParseUint(idParam, 10, 32)
	if err != nil {
		logger.Warn("解析用户ID失败", zap.Error(err), zap.String("id", idParam))
		common.Error(ctx, err)
		return
	}

	user, err := c.userService.GetUserByID(uint(id))
	if err != nil {
		logger.Error("获取用户信息失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, user)
}

// Update godoc
// @Summary 更新用户信息
// @Description 更新指定用户的信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "用户ID"
// @Param request body request.UserUpdateRequest true "用户信息"
// @Success 200 {object} resp.Response "成功"
// @Router /users/{id} [put]
func (c *UserController) Update(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		logger.Warn("解析用户ID失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	var req request.UserUpdateRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定更新用户请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	req.ID = uint(id)
	if err := c.userService.UpdateUser(&req); err != nil {
		logger.Error("更新用户失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// Delete godoc
// @Summary 删除用户
// @Description 删除指定用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "用户ID"
// @Success 200 {object} resp.Response "成功"
// @Router /users/{id} [delete]
func (c *UserController) Delete(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		logger.Warn("解析用户ID失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	if err := c.userService.DeleteUser(uint(id)); err != nil {
		logger.Error("删除用户失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// SetStatus godoc
// @Summary 设置用户状态
// @Description 启用或禁用用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body request.UserStatusRequest true "状态信息"
// @Success 200 {object} resp.Response "成功"
// @Router /users/status [put]
func (c *UserController) SetStatus(ctx *gin.Context) {
	var req request.UserStatusRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定用户状态请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	if err := c.userService.SetUserStatus(&req); err != nil {
		logger.Error("设置用户状态失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// UpdatePassword godoc
// @Summary 修改密码
// @Description 修改用户密码
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body request.PasswordUpdateRequest true "密码信息"
// @Success 200 {object} resp.Response "成功"
// @Router /users/password [put]
func (c *UserController) UpdatePassword(ctx *gin.Context) {
	// 获取当前用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		logger.Error("用户未认证或未找到用户ID")
		common.Error(ctx, errors.New("用户未认证"))
		return
	}

	// 确保userID是uint类型
	var uid uint
	switch v := userID.(type) {
	case uint:
		uid = v
	case int:
		uid = uint(v)
	case float64:
		uid = uint(v)
	case string:
		parsedID, err := strconv.ParseUint(v, 10, 32)
		if err != nil {
			logger.Error("无法将用户ID转换为uint", zap.Error(err), zap.Any("userID", userID))
			common.Error(ctx, errors.New("无效的用户ID"))
			return
		}
		uid = uint(parsedID)
	default:
		logger.Error("用户ID类型不支持", zap.String("type", fmt.Sprintf("%T", userID)))
		common.Error(ctx, errors.New("无效的用户ID类型"))
		return
	}

	var req request.PasswordUpdateRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定修改密码请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	if err := c.userService.UpdatePassword(&req, uid); err != nil {
		logger.Error("修改密码失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// Profile godoc
// @Summary 更新个人信息
// @Description 更新当前用户的个人信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body request.ProfileUpdateRequest true "个人信息"
// @Success 200 {object} resp.Response "成功"
// @Router /users/profile [put]
func (c *UserController) Profile(ctx *gin.Context) {
	// 使用middleware中设置的正确键名获取userID
	userID, exists := ctx.Get("userID")
	if !exists {
		logger.Error("用户未认证或未找到用户ID")
		common.Error(ctx, errors.New("用户未认证"))
		return
	}

	var req request.ProfileUpdateRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定更新个人信息请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	if err := c.userService.UpdateProfile(userID.(uint), &req); err != nil {
		logger.Error("更新个人信息失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, nil)
}

// GetCurrentUserInfo godoc
// @Summary 获取当前用户信息
// @Description 获取当前登录用户的详细信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Success 200 {object} resp.Response{data=response.UserInfo} "成功"
// @Router /users/info [get]
func (c *UserController) GetCurrentUserInfo(ctx *gin.Context) {
	logger.Info("GetCurrentUserInfo: 开始获取当前用户信息")
	logger.Info("请求路径:", zap.String("path", ctx.FullPath()))
	logger.Info("请求方法:", zap.String("method", ctx.Request.Method))
	logger.Info("Authorization头:", zap.String("auth", ctx.GetHeader("Authorization")))

	// 使用middleware中设置的正确键名获取userID
	userID, exists := ctx.Get("userID")
	if !exists {
		logger.Error("GetCurrentUserInfo: 用户未认证或未找到用户ID")
		common.Error(ctx, errors.New("用户未认证"))
		return
	}

	logger.Info("GetCurrentUserInfo: 获取到用户ID", zap.Any("userID", userID))

	// 确保userID是有效的uint类型
	var uid uint
	switch v := userID.(type) {
	case uint:
		uid = v
	case int:
		uid = uint(v)
	case float64:
		uid = uint(v)
	case string:
		parsedID, err := strconv.ParseUint(v, 10, 32)
		if err != nil {
			logger.Error("GetCurrentUserInfo: 无法将用户ID转换为uint", zap.Error(err), zap.Any("userID", userID))
			common.Error(ctx, errors.New("无效的用户ID"))
			return
		}
		uid = uint(parsedID)
	default:
		logger.Error("GetCurrentUserInfo: 用户ID类型不支持", zap.String("type", fmt.Sprintf("%T", userID)))
		common.Error(ctx, errors.New("无效的用户ID类型"))
		return
	}

	logger.Info("GetCurrentUserInfo: 转换后的用户ID", zap.Uint("uid", uid))

	// 1. 获取基础用户信息 (model.User)
	userModel, err := c.userService.GetUserByID(uid)
	if err != nil {
		logger.Error("GetCurrentUserInfo: 获取基础用户信息失败", zap.Error(err), zap.Uint("userID", uid))
		common.Error(ctx, err)
		return
	}

	// 2. 获取角色名称
	roleName, err := c.userService.GetRoleNameByID(userModel.RoleID)
	if err != nil {
		logger.Error("GetCurrentUserInfo: 获取角色名称失败", zap.Error(err), zap.Uint("roleID", userModel.RoleID))
		// 不阻塞流程，但 roles 数组可能为空
		roleName = ""
	}

	// 3. 构建 response.UserInfo 结构
	userInfo := response.UserInfo{
		ID:       userModel.ID,
		Username: userModel.Username,
		Nickname: userModel.Nickname,
		Email:    userModel.Email,
		Phone:    userModel.Phone,
		Avatar:   userModel.Avatar,
		RoleID:   userModel.RoleID,
		Status:   userModel.Status,
		Roles:    []string{}, // Initialize as empty slice
	}
	if roleName != "" {
		userInfo.Roles = append(userInfo.Roles, roleName)
	}

	logger.Info("GetCurrentUserInfo: 成功获取用户信息",
		zap.String("username", userInfo.Username),
		zap.Uint("role_id", userInfo.RoleID),
		zap.Strings("roles", userInfo.Roles),
		zap.String("avatar", userInfo.Avatar))

	// 4. 返回 response.UserInfo 结构
	common.Success(ctx, userInfo)
}

// UploadAvatar godoc
// @Summary 上传头像
// @Description 上传用户头像
// @Tags 用户管理
// @Accept multipart/form-data
// @Produce json
// @Security Bearer
// @Param file formData file true "头像文件"
// @Success 200 {object} resp.Response{data=string} "成功"
// @Router /users/avatar [post]
func (c *UserController) UploadAvatar(ctx *gin.Context) {
	// 使用middleware中设置的正确键名获取userID
	userID, exists := ctx.Get("userID")
	if !exists {
		logger.Error("用户未认证或未找到用户ID")
		common.Error(ctx, errors.New("用户未认证"))
		return
	}

	file, err := ctx.FormFile("file")
	if err != nil {
		logger.Warn("获取上传文件失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	url, err := c.userService.UploadAvatar(userID.(uint), file)
	if err != nil {
		logger.Error("上传头像失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	common.Success(ctx, url)
}

// GetRecycleList godoc
// @Summary 获取回收站用户列表
// @Description 获取回收站中的用户列表，支持分页和搜索
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param keyword query string false "搜索关键词"
// @Success 200 {object} common.Response{data=response.UserListResponse} "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /system/user/recycle [get]
func (c *UserController) GetRecycleList(ctx *gin.Context) {
	var req request.UserListRequest
	if err := ctx.ShouldBindQuery(&req); err != nil {
		logger.Warn("绑定回收站用户列表请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}

	// TODO: 实现从回收站获取用户列表的服务
	// 这里暂时返回空列表
	common.Success(ctx, gin.H{
		"list":  []interface{}{},
		"total": 0,
		"page":  req.Page,
		"size":  req.PageSize,
	})
}

// BatchDelete godoc
// @Summary 批量删除用户
// @Description 批量删除指定用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body struct{IDs []uint "用户ID数组"} true "用户ID列表"
// @Success 200 {object} common.Response "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /users/batch [delete]
func (c *UserController) BatchDelete(ctx *gin.Context) {
	var req struct {
		IDs []uint `json:"ids" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定批量删除用户请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// 检查是否包含管理员
	for _, id := range req.IDs {
		if id == 1 {
			logger.Warn("尝试删除管理员", zap.Uint("user_id", id))
			common.Error(ctx, errors.New("管理员不能删除"))
			return
		}
	}

	// 批量删除用户
	for _, id := range req.IDs {
		if err := c.userService.DeleteUser(id); err != nil {
			logger.Error("删除用户失败", zap.Error(err), zap.Uint("user_id", id))
			common.Error(ctx, err)
			return
		}
	}

	logger.Info("批量删除用户成功", zap.Any("user_ids", req.IDs))
	common.Success(ctx, nil)
}

// RealDelete godoc
// @Summary 真实删除用户
// @Description 从数据库中永久删除用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body struct{IDs []uint "用户ID数组"} true "用户ID列表"
// @Success 200 {object} common.Response "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /users/real [delete]
func (c *UserController) RealDelete(ctx *gin.Context) {
	var req struct {
		IDs []uint `json:"ids" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定真实删除用户请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// 检查是否包含管理员
	for _, id := range req.IDs {
		if id == 1 {
			logger.Warn("尝试删除管理员", zap.Uint("user_id", id))
			common.Error(ctx, errors.New("管理员不能删除"))
			return
		}
	}

	// TODO: 实现真实删除用户的服务
	logger.Info("真实删除用户成功", zap.Any("user_ids", req.IDs))
	common.Success(ctx, nil)
}

// Recovery godoc
// @Summary 恢复用户
// @Description 从回收站恢复删除的用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body struct{IDs []uint "用户ID数组"} true "用户ID列表"
// @Success 200 {object} common.Response "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /users/recovery [put]
func (c *UserController) Recovery(ctx *gin.Context) {
	var req struct {
		IDs []uint `json:"ids" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定恢复用户请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// TODO: 实现恢复用户的服务
	logger.Info("恢复用户成功", zap.Any("user_ids", req.IDs))
	common.Success(ctx, nil)
}

// ClearCache godoc
// @Summary 清除用户缓存
// @Description 清除指定用户的缓存数据
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body struct{ID uint "用户ID"} true "用户ID"
// @Success 200 {object} common.Response "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /users/cache [delete]
func (c *UserController) ClearCache(ctx *gin.Context) {
	var req struct {
		ID uint `json:"id" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定清除用户缓存请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// TODO: 实现清除用户缓存的服务
	logger.Info("清除用户缓存成功", zap.Uint("user_id", req.ID))
	common.Success(ctx, nil)
}

// SetHomePage godoc
// @Summary 设置用户首页
// @Description 设置用户登录后的首页
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body struct{ID uint "用户ID";Dashboard string "首页标识"} true "首页信息"
// @Success 200 {object} common.Response "成功"
// @Failure 400 {object} common.Response "请求错误"
// @Failure 500 {object} common.Response "内部错误"
// @Router /users/homepage [put]
func (c *UserController) SetHomePage(ctx *gin.Context) {
	var req struct {
		ID        uint   `json:"id" binding:"required"`
		Dashboard string `json:"dashboard" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Warn("绑定设置用户首页请求参数失败", zap.Error(err))
		common.Error(ctx, err)
		return
	}

	// TODO: 实现设置用户首页的服务
	logger.Info("设置用户首页成功", zap.Uint("user_id", req.ID), zap.String("dashboard", req.Dashboard))
	common.Success(ctx, nil)
}
